using System;

namespace TestCases.Utils.Pairs
{
    public struct ValuePair<TLeft, TRight> : IPair<TLeft, TRight>, IEquatable<IPair<TLeft, TRight>>
    {
        public ValuePair(TLeft left, TRight right) : this()
        {
            Left = left;
            Right = right;
        }

        public ValuePair(IPair<TLeft, TRight> pair) : this()
        {
            Left = pair.Left;
            Right = pair.Right;
        }

        public bool Equals(IPair<TLeft, TRight> other)
        {
            return Equals(other.Left, Left) && Equals(other.Right, Right);
        }

        public TLeft Left { get; set; }
        public TRight Right { get; set; }

        public override bool Equals(object obj)
        {
            if (!(obj is IPair<TLeft, TRight>))
            {
                return false;
            }
            return Equals((IPair<TLeft, TRight>) obj);
        }

        public override int GetHashCode()
        {
            var leftHash = (!Equals(Left, default(TLeft))) ? Left.GetHashCode() : 0;
            var rightHash = (!Equals(Right, default(TRight))) ? Right.GetHashCode() : 0;
            return leftHash ^ (rightHash*2);
        }

        public override string ToString()
        {
            return "[{Left}, {Right}]".FormatWith(new {Left = Left.ToValueString(), Right = Right.ToValueString()});
        }
    }
}